﻿using B.Z.BasicData.API.Read.DTO;
using B.Z.BasicData.Domain.Entity.Authorize;
using B.Z.BasicData.ErrorCode;
using B.Z.BasicData.Infrastructure;
using MediatR;
using System.Collections.Generic;
using System.Security.Cryptography;

namespace B.Z.BasicData.API.Read.Application.Menu
{
    public class MenuRoleQueryCommandHandler : IRequestHandler<MenuRoleQueryCommand, APIResult<List<RoleMenuDto>>>
    {
        private readonly IBaseRepository<T_RoleMenu> rmRepository;
        private readonly IBaseRepository<T_Menu> menuRepository;

        public MenuRoleQueryCommandHandler(IBaseRepository<T_RoleMenu> rmRepository, IBaseRepository<T_Menu> menuRepository)
        {
            this.rmRepository = rmRepository;
            this.menuRepository = menuRepository;
        }

        public Task<APIResult<List<RoleMenuDto>>> Handle(MenuRoleQueryCommand request, CancellationToken cancellationToken)
        {
            APIResult<List<RoleMenuDto>> result = new APIResult<List<RoleMenuDto>>();
            result.Code = APIEnum.ok;
            result.Message = "获取成功";
            List<int> allIdList = new List<int>();
            //根据角色Id数组获取到所有的菜单ID
            var midList= rmRepository.GetAll().Where(p => request.RidList.Contains(p.Rid)).Select(x => x.Mid).Distinct().ToList();
            //根据菜单ID获取到角色所拥有的菜单列表
            var list = menuRepository.GetAll().Where(p => midList.Contains(p.Id)).ToList();
            ////获取角色所用有的所有父级Id
            var pList = list.Select(x => x.Pid).ToList();
            ////将获取到的父级Id添加到总的Id数组中
            allIdList.AddRange(pList);
            allIdList.AddRange(midList);
            //while (!allIdList.Contains(0)) 
            //{

            //}
            List<T_Menu> path = new List<T_Menu>();
            //当不不存在父节点数组中没有0时
            if (!pList.Contains(0))
            {
                foreach (var item in midList)
                {
                    var menu = menuRepository.GetAll().FirstOrDefault(p => p.Id == item);
                    path.Add(menu);
                    while (menu != null && menu.Pid != 0)
                    {
                        menu = menuRepository.GetAll().FirstOrDefault(p => p.Id == menu.Pid);
                        path.Add(menu);
                    }
                    if (menu != null)
                        path.Add(menu);
                }
            }
            else 
            {
               path= menuRepository.GetAll().Where(p => allIdList.Contains(p.Id)).ToList();
            }
            result.Data = GetList(path, 0);
            return Task.FromResult(result);
        }

        public List<RoleMenuDto> GetList(List<T_Menu> list, int pid) 
        {
            var plist = menuRepository.GetAll().Where(x => list.Select(x => x.Id).Contains(x.Id) && x.Pid == pid).ToList();
            List<RoleMenuDto> dtos = new List<RoleMenuDto>();
            
            foreach (var item in plist)
            {
                RoleMenuDto dto = new RoleMenuDto();
                dto.Id = item.Id;
                dto.Label = item.MenuName;
                dto.Url = item.Url;
                dto.Children = GetList(list, item.Id);
                dtos.Add(dto);
            }
            return dtos;
        }
    }
}
